package com.hedl.classroom.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hedl.classroom.base.exception.CommonResult;
import com.hedl.classroom.base.exception.OnlinecClassroomException;
import com.hedl.classroom.mapper.TeachplanMapper;
import com.hedl.classroom.mapper.TeachplanMediaMapper;
import com.hedl.classroom.model.dto.BindTeachplanMediaDto;
import com.hedl.classroom.model.dto.SaveTeachplanDto;
import com.hedl.classroom.model.dto.TeachplanDto;
import com.hedl.classroom.model.po.Teachplan;
import com.hedl.classroom.model.po.TeachplanMedia;
import com.hedl.classroom.service.TeachplanService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
public class TeachplanServiceImpl implements TeachplanService {

    @Resource
    private TeachplanMapper teachplanMapper;

    @Resource
    private TeachplanMediaMapper teachplanMediaMapper;

    @Override
    public List<TeachplanDto> selectTreeNodes(Long courseId) {
        List<TeachplanDto> teachplanDtos = teachplanMapper.selectTreeNodes(courseId);
        return teachplanDtos;
    }

    @Override
    public void saveTeachplan(SaveTeachplanDto saveTeachplanDto) {
        //通过课程计划id判读是新增和修改
        Long id = saveTeachplanDto.getId();
        if (id == null){
            //新增
            Teachplan teachplan = new Teachplan();
            BeanUtils.copyProperties(saveTeachplanDto,teachplan);
            //确定排序字段，找到它的同级节点个数，排序字段就是个数加一
            Long parentId = saveTeachplanDto.getParentid();
            Long courseId = saveTeachplanDto.getCourseId();
            // 设置排序号
            teachplan.setOrderby(getTeachplanCount(courseId,parentId)+1);
            teachplan.setCreateDate(LocalDateTime.now());
            teachplan.setChangeDate(LocalDateTime.now());
            int insert = teachplanMapper.insert(teachplan);
            if (insert <= 0) OnlinecClassroomException.cast("新增失败！");
        }else{
            //修改
            Teachplan teachplan = teachplanMapper.selectById(id);
            if (teachplan == null){
                OnlinecClassroomException.cast("数据不存在！");
            }
            BeanUtils.copyProperties(saveTeachplanDto,teachplan);
            teachplan.setChangeDate(LocalDateTime.now());
            int i = teachplanMapper.updateById(teachplan);
            if (i <= 0) OnlinecClassroomException.cast("修改失败！");
        }
    }

    private Integer getTeachplanCount(Long courseId,Long parentId){
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Teachplan::getCourseId,courseId);
        queryWrapper.eq(Teachplan::getParentid,parentId);
        return teachplanMapper.selectCount(queryWrapper);
    }

    @Override
    public CommonResult selectTeachplanByid(Long id) {
        Integer count = teachplanMapper.selectTeachplanByid(id);
        if (count == 0){
            int i = teachplanMapper.deleteById(id);
            if (i <= 0){
                OnlinecClassroomException.cast("删除失败！");
            }else {
                return CommonResult.result();
            }
        }else{
            return CommonResult.error("课程计划信息还有子级信息，无法操作");
        }
        return null;
    }

    @Override
    @Transactional
    public void orderByTeachplan(String moveType,Long id) {
        Teachplan teachplan = teachplanMapper.selectById(id);
        //获取层级和当前orderby，章节移动和小节移动的处理方式不同
        Integer grade = teachplan.getGrade();
        Integer orderby = teachplan.getOrderby();
        //章节移动是比较同一课程id下的orderby
        Long courseId = teachplan.getCourseId();
        //小节移动是比较同一章节id下的orderby
        Long parentid = teachplan.getParentid();
        if("moveup".equals(moveType)){
            if (grade == 1) {
                // 章节上移，找到上一个章节的orderby，然后与其交换orderby
                // SELECT * FROM teachplan WHERE courseId = 117 AND grade = 1  AND orderby < 1 ORDER BY orderby DESC LIMIT 1
                LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Teachplan::getGrade, 1)
                        .eq(Teachplan::getCourseId, courseId)
                        .lt(Teachplan::getOrderby, orderby)
                        .orderByDesc(Teachplan::getOrderby)
                        .last("LIMIT 1");
                Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
                exchangeOrderby(teachplan, tmp);
            } else if (grade == 2) {
                // 小节上移
                // SELECT * FROM teachplan WHERE parentId = 268 AND orderby < 5 ORDER BY orderby DESC LIMIT 1
                LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Teachplan::getParentid, parentid)
                        .lt(Teachplan::getOrderby, orderby)
                        .orderByDesc(Teachplan::getOrderby)
                        .last("LIMIT 1");
                Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
                exchangeOrderby(teachplan, tmp);
            }
        }else if ("movedown".equals(moveType)){
            if (grade == 1) {
                // 章节下移
                // SELECT * FROM teachplan WHERE courseId = 117 AND grade = 1 AND orderby > 1 ORDER BY orderby ASC LIMIT 1
                LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Teachplan::getCourseId, courseId)
                        .eq(Teachplan::getGrade, grade)
                        .gt(Teachplan::getOrderby, orderby)
                        .orderByAsc(Teachplan::getOrderby)
                        .last("LIMIT 1");
                Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
                exchangeOrderby(teachplan, tmp);
            } else if (grade == 2) {
                // 小节下移
                // SELECT * FROM teachplan WHERE parentId = 268 AND orderby > 1 ORDER BY orderby ASC LIMIT 1
                LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Teachplan::getParentid, parentid)
                        .gt(Teachplan::getOrderby, orderby)
                        .orderByAsc(Teachplan::getOrderby)
                        .last("LIMIT 1");
                Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
                exchangeOrderby(teachplan, tmp);
            }

        }
    }

    @Override
    @Transactional
    public TeachplanMedia associationMedia(BindTeachplanMediaDto bindTeachplanMediaDto) {
        Long teachplanId = bindTeachplanMediaDto.getTeachplanId();
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if (teachplan == null){
            OnlinecClassroomException.cast("教学计划不存在!");
        }
        Integer grade = teachplan.getGrade();
        if (grade != 2){
            OnlinecClassroomException.cast("只允许第二级教学计划绑定媒资文件!");
        }
        //课程id
        Long courseId = teachplan.getCourseId();
        LambdaQueryWrapper<TeachplanMedia> queryWrapper = new LambdaQueryWrapper<TeachplanMedia>();
        queryWrapper.eq(TeachplanMedia::getTeachplanId,bindTeachplanMediaDto.getTeachplanId());
        //先删除原有记录，根据课程id删除它所绑定的媒资
        int delete = teachplanMediaMapper.delete(queryWrapper);

        //在添加新纪录
        TeachplanMedia teachplanMedia = new TeachplanMedia();
        BeanUtils.copyProperties(bindTeachplanMediaDto,teachplanMedia);
        teachplanMedia.setCourseId(courseId);
        teachplanMedia.setMediaFilename(bindTeachplanMediaDto.getFileName());
        teachplanMedia.setCreateDate(LocalDateTime.now());
        int insert = teachplanMediaMapper.insert(teachplanMedia);
        if (insert <= 0) OnlinecClassroomException.cast("新增失败！");

        return teachplanMedia;
    }

    @Override
    public void deleteTeachplanMedia(Long teachplanId, String mediaId) {
        if (teachplanId == null && mediaId.equals("")){
            OnlinecClassroomException.cast("课程id和媒资id不能为空！");
        }
        LambdaQueryWrapper<TeachplanMedia> queryWrapper = new LambdaQueryWrapper<TeachplanMedia>();
        queryWrapper.eq(TeachplanMedia::getTeachplanId,teachplanId);
        queryWrapper.eq(TeachplanMedia::getMediaId,mediaId);

        TeachplanMedia teachplanMedia = teachplanMediaMapper.selectOne(queryWrapper);
        if (teachplanMedia == null){
            OnlinecClassroomException.cast("媒资视频为空！");
        }
        int delete = teachplanMediaMapper.delete(queryWrapper);
        if (delete <= 0) OnlinecClassroomException.cast("删除失败！");

    }

    @Override
    public Teachplan getTeachplan(Long teachplanId) {
        return teachplanMapper.selectById(teachplanId);
    }

    /**
     * 交换两个Teachplan的orderby
     * @param teachplan
     * @param tmp
     */
    private void exchangeOrderby(Teachplan teachplan, Teachplan tmp) {
        if (tmp == null)
            OnlinecClassroomException.cast("已经到头啦，不能再移啦");
        else {
            // 交换orderby，更新
            Integer orderby = teachplan.getOrderby();
            Integer tmpOrderby = tmp.getOrderby();
            teachplan.setOrderby(tmpOrderby);
            teachplan.setChangeDate(LocalDateTime.now());
            tmp.setOrderby(orderby);
            tmp.setChangeDate(LocalDateTime.now());
            teachplanMapper.updateById(tmp);
            teachplanMapper.updateById(teachplan);
        }
    }
}
